package com.example.jnet.services;

import com.example.jnet.pojo.MessageProtocol;
import com.example.jnet.tools.ToolUtils;
import io.netty.channel.ChannelHandlerContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Service;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Service
public class ServiceManager implements ApplicationContextAware, InitializingBean {
    private static Logger logger = LoggerFactory.getLogger(ServiceManager.class);

    private Map<Integer, IMessageService> serviceMap = new ConcurrentHashMap();
    private ApplicationContext applicationContext;

    @Override
    public void afterPropertiesSet() throws Exception {
        Map<String, IMessageService> map = applicationContext.getBeansOfType(IMessageService.class);
        for (IMessageService service : map.values()) {
            if (!serviceMap.containsKey(service.getHandlerType())) {
                logger.info(" class = [{}] service = [{}]", service.getHandlerType(), service);
                serviceMap.put(service.getHandlerType(), service);
            } else {
                logger.error("Duplicate controller  class = [{}] service = [{}]", service.getHandlerType(), service);
            }
        }
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    public void dispatcherMsg(ChannelHandlerContext ctx, MessageProtocol msg) {
        if (msg == null) {
            logger.error("dispatcherMsg failed, msg is null", ctx.channel().toString());
            return;
        }

        try {
            boolean isFind = false;
            Integer type = ToolUtils.bytes2Int(msg.getType());
            if (serviceMap.containsKey(type)) {
                isFind = true;
                serviceMap.get(type).doService(ctx, msg);
            }
            if (!isFind) {
                logger.error("not find service: " + msg.toString());
            }
        } catch (Exception e) {
            logger.error("e:" + e.getMessage());
        }
    }
}